package com.gaussian.property.app.controller;

import com.gaussian.property.app.service.CheckService;
import com.gaussian.property.app.vo.*;
import com.gaussian.property.module.biz.entity.AppUser;
import com.gaussian.property.module.biz.entity.CheckTable;
import com.gaussian.property.module.biz.entity.ProjectCheckTable;
import com.gaussian.property.module.biz.service.IProjectCheckTableService;
import com.songqi.common.core.domain.R;
import com.songqi.common.web.request.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.time.LocalDate;

import java.util.List;

/**
 * @description:
 * @author: songqi(13776346982)
 * @date: 2024/4/9 23:32
 */
@Api(tags = "稽核相关操作")
@RestController
@Validated
@RequestMapping("check/")
public class CheckController extends BaseController {

    @Resource
    private CheckService checkService;
    @Resource
    private IProjectCheckTableService iProjectCheckTableService;

    @ApiOperation("根据项目Id查询项目配置的稽核表")
    @GetMapping("queryConfigCheckTable")
    public R<List<CheckTableVo>> queryConfigCheckTable(@NotBlank(message = "项目未配置稽核表，联系管理员") @ApiParam("项目id") String projectId) {
        return R.success(checkService.queryConfigCheckTable(projectId)) ;
    }


    @ApiOperation("根据稽核表id查询稽核表详细信息。发起稽核前查出空表")
    @GetMapping("queryCheckTableDetail")
    public R<CheckTableDetailVo> queryCheckTableDetail(@NotBlank(message = "项目未配置稽核表，联系管理员") @ApiParam("项目id") String projectId,
                                                       @NotBlank(message = "稽核表id必传") @ApiParam("稽核表id") String checkTableId,
                                                       @ApiParam("标准关键字") String searchKey) {
        return R.success(checkService.queryCheckTableDetail(projectId, checkTableId, searchKey));
    }

    @ApiOperation("判断用户是否可以开始稽核。可以-true,不可以-false")
    @GetMapping("canStartCheck")
    public R<Boolean> canStartCheck(@NotBlank(message = "项目未配置稽核表，联系管理员") @ApiParam("项目id") String projectId,
                                    @NotBlank(message = "稽核表id必传") @ApiParam("稽核表id") String checkTableId){
        AppUser appUser = (AppUser) getTokenUser();
        ProjectCheckTable projectCheckTable = iProjectCheckTableService.queryProjectCheckTable(projectId, checkTableId);
        checkService.canStartCheck(projectCheckTable, appUser);
        return R.success(true);
    }

    @ApiOperation("获取临时稽核记录id。用来保存前端二级页面提交的数据。")
    @GetMapping("getTempProjectCheckRecordId")
    public R<String> getTempProjectCheckRecordId(@NotBlank(message = "项目未配置稽核表，联系管理员") @ApiParam("项目id") String projectId,
                                                 @NotBlank(message = "稽核表id必传") @ApiParam("稽核表id") String checkTableId){
        return R.success(checkService.queryTempProjectCheckRecordId(projectId, checkTableId));
    }


    @ApiOperation("获取前端二级页面临时提交的打分数据")
    @GetMapping("getTempCheckItem")
    public R<CheckItem> getTempCheckItem(@NotBlank(message = "临时稽核记录id必传") @ApiParam("临时稽核记录id") String tempProjectCheckRecordId,
                                         @NotBlank(message = "标准id必传") @ApiParam("标准id") String checkStandardId){
        return R.success(checkService.queryTempCheckItem(tempProjectCheckRecordId, checkStandardId));
    }

    @ApiOperation("临时保存前端二级页面提交的打分数据")
    @PostMapping("saveTempCheckItem")
    public R<Void> saveTempCheckItem(@RequestBody @Validated TempCheckItemForm tempCheckItemForm){
        checkService.saveTempCheckItem(tempCheckItemForm);
        return success();
    }

    @ApiOperation("保存用户提交的稽核记录")
    @PostMapping("saveCheck")
    public R<Void> saveCheck(@Validated @RequestBody CheckForm checkForm){
        AppUser appUser = (AppUser) getTokenUser();
        checkService.saveCheck(checkForm, appUser);
        checkService.cleanTempProjectCheckRecord(checkForm.getTempProjectCheckRecordId());
        return success();
    }

    @ApiOperation("查询今天/7天、30天tab标签的稽核模块列表。")
    @GetMapping("queryCheckModule")
    public R<List<CheckModuleLite>> queryCheckModule(@Validated @NotBlank(message = "项目未配置稽核表，联系管理员") @ApiParam("项目id") String projectId,
                                                          @Validated @NotBlank(message = "稽核表id必传") @ApiParam("稽核表id") String checkTableId,
                                                          @NotBlank(message = "统计范围") @ApiParam("统计范围。today-今天、7-过去7天、30-过去30天")
                                                         @Validated @Pattern(regexp = "today|7|30", message = "统计范围参数不正确") String range) {
        return R.success(checkService.queryCheckModuleLiteList(projectId, checkTableId, range));
    }




    @ApiOperation("查询今天/7天/过去30天tab标签的评分记录。")
    @GetMapping("queryStandardScore")
    public R<CheckStandardScoreStatistic> queryStandardScore(@Validated @NotBlank(message = "项目未配置稽核表，联系管理员") @ApiParam("项目id") String projectId,
                                                             @Validated  @NotBlank(message = "稽核表id必传") @ApiParam("稽核表id") String checkTableId,
                                                                  @ApiParam("模块id。可为空") String checkModuleId,
                                                             @Validated @NotBlank(message = "统计范围") @ApiParam("统计范围。today-今天、7-过去7天、30-过去30天")
                                                                 @Pattern(regexp = "today|7|30", message = "统计范围参数不正确") String range){
        return R.success(checkService.queryCheckStandardScoreStatistic(projectId, checkTableId, checkModuleId, range));
    }



    @ApiOperation("查询今天/过去7天/过去30天稽核补充内容")
    @GetMapping("queryCheckRecord")
    public R<List<CheckRecordVo>> queryCheckRecord(@NotBlank(message = "项目未配置稽核表，联系管理员") @ApiParam("项目id") String projectId,
                                                   @NotBlank(message = "稽核表id必传") @ApiParam("稽核表id") String checkTableId,
                                                   @NotBlank(message = "统计范围") @ApiParam("统计范围。today-今天、7-过去7天、30-过去30天") String range){
        return R.success(checkService.queryCheckRecordVo(projectId, checkTableId, range));
    }


    @ApiOperation("查询今天/过去7天/过去30天稽核标准评分统计详情")
    @GetMapping("queryCheckStandardStatisticDetail")
    public R<CheckStandardStatisticDetail> queryCheckStandardStatisticDetail(@NotBlank(message = "项目未配置稽核表，联系管理员") @ApiParam("项目id") String projectId,
                                                                        @NotBlank(message = "稽核表id必传") @ApiParam("稽核表id") String checkTableId,
                                                                        @NotBlank(message = "标准id必传") @ApiParam("标准id") String checkStandardId,
                                                                        @NotBlank(message = "统计范围") @ApiParam("统计范围。today-今天、7-过去7天、30-过去30天") String range){
        return R.success(checkService.queryCheckStandardStatisticDetail(projectId, checkTableId, checkStandardId, range));
    }




    @ApiOperation("查询稽核表今天/过去7天/过去30天得分（图表展示）")
    @GetMapping("queryDeductionDatum")
    public R<Chart> queryDeductionDatum(@NotBlank(message = "项目未配置稽核表，联系管理员") @ApiParam("项目id") String projectId,
                                                       @NotBlank(message = "稽核表id必传") @ApiParam("稽核表id") String checkTableId,
                                                       @NotBlank(message = "统计范围必传") @ApiParam("统计范围。today-今天、7-过去7天、30-过去30天") String range) {
        DateRange timeRange = getDateRange(range);
        Chart chart = new Chart();
        List<DeductionDatum> deductionDatumList = checkService.queryDeductionDatum(projectId, checkTableId, timeRange.startDate, timeRange.endDate);
        CheckTable checkTable = checkService.getById(checkTableId);
        chart.setDeductionDatumList(deductionDatumList);
        if(checkTable != null){
            chart.setScore(checkTable.getScore());
        }
        return R.success(chart);
    }




    private DateRange getDateRange(String range) {
        LocalDate startDate = LocalDate.now();
        LocalDate endDate = LocalDate.now();
        if ("7".equals(range)) {
            endDate = LocalDate.now().minusDays(1L);
            startDate = LocalDate.now().minusDays(7L);
        }
        if ("30".equals(range)) {
            endDate = LocalDate.now().minusDays(1L);
            startDate = LocalDate.now().minusDays(30L);
        }
        return new DateRange(startDate, endDate);
    }

    private static class DateRange {
        public final LocalDate startDate;
        public final LocalDate endDate;

        public DateRange(LocalDate startDate, LocalDate endDate) {
            this.startDate = startDate;
            this.endDate = endDate;
        }
    }



}
